<template>
  <div>
    <div class="img-list">
      <Draggable
          :list="list"
          :force-fallback="true"
          :sort="sort"
          item-key="url"
          @end="draggableEnd"
          animation="300"
      >
        <template #item="{element,index}">
          <div class="img-item"  :style="imgStyle">
            <el-image
                :style="imgStyle"
                :src="element[itemName]"
                :fit="fit"
                :preview-teleported="true"
            />
            <div class="img-item-icon" :class="list.length>1?'icon-move':''">
              <el-icon @click="showImgView(index)" color="#fff" size="18" title="放大" style="cursor: pointer;" ><ZoomIn /></el-icon>
              <div  v-if="!disabled" style="width: 10px"></div>
              <el-icon @click="deleteImg(index)" v-if="!disabled" color="#fff" size="18" title="删除" style="cursor: pointer;" ><Delete /></el-icon>
            </div>
          </div>
        </template>
        <template #footer>
          <div @click="addImg" v-if="selectNumEvent&&!disabled" class="add-icon"  :style="imgStyle">
            <el-icon><Plus /></el-icon>
          </div>
        </template>
      </Draggable>
    </div>
    <el-link type="danger" v-if="hint">{{hint}}</el-link>
  </div>

  <el-image-viewer :initial-index="initialIndex" @close="() => { showViewer = false }" v-if="showViewer" :url-list="urlList" />
  <ImgIndex ref="ImgIndexRef" runType="arrayObj" v-model="indexImgList" :selectNum="selectNum" :channel="channel" @imgAdminRes="imgAdminRes" ></ImgIndex>
</template>

<script setup>
  import {computed} from "vue";
  import {deepClone} from "@/utils";
  import ImgIndex from "./index";
  //https://www.itxst.com/vue-draggable-next/tutorial.html
  import Draggable from "vuedraggable";
  const props=defineProps({
    //接收字符串："url,url,url"    数组：[{url:""},{url:""}]或者["url","url"]
    modelValue: [String, Array],
    //modelValue返回和接收格式，string 返回"url,url,url" ；arrayStr 返回["url","url"] ； arrayObj 返回[{url:""},{url:""}]
    runType:{
      type:String,
      default:"string"
    },
    //图片的属性名称
    itemName:{
      type:String,
      default:"url"
    },
    //上传个数，为0不限制
    selectNum:{
      type:Number,
      default:0
    },
    //是否禁用
    disabled:{
      type:Boolean,
      default:false
    },
    //图片大小
    imgStyle:{
      type:String,
      default:"width: 100px; height: 100px"
    },
    //图片展示兼容 fill contain cover none scale-down
    fit:{
      type:String,
      default:""
    },
    //区分模块(暂时没用上)
    channel:{
      type:Number,
      default:1
    },
    //提示语，为空不提示
    hint:{
      type:String,
      default:""
    },
    //是否开始拖拽排序
    sort:{
      type:Boolean,
      default:true
    }
  });
  const {proxy}=getCurrentInstance();
  const emit=defineEmits();
  const showViewer = ref(false)
  const urlList = ref([]);
  const initialIndex=ref(0);
  const list=ref([]);
  //给图片库 v-model
  const indexImgList=ref([]);
  const selectNumEvent=computed(()=>{
    if(props.selectNum===0) return true;
    return list.value.length<props.selectNum;
  })
  watch(() => props.modelValue, val => {
    if (val) {
      switch (props.runType) {
        case "string":
          const arr= val.split(",");
          list.value = arr.map(item => ({ [props.itemName]: item }));
          break;
        case "arrayStr":
          list.value = val.map(item => ({ [props.itemName]: item }));
          break;
        case "arrayObj":
            list.value = val;
          break;
        default:
          list.value = val;
      }
      urlList.value = list.value.map(item => item[props.itemName]);
      indexImgList.value=deepClone(list.value);
    } else {
      urlList.value=list.value =[];
      indexImgList.value=[];
      return [];
    }
  },{ deep: true, immediate: true });
  // 对象转成指定字符串分隔
  function listToString(list) {
    switch (props.runType) {
      case "string":
        return list.map(t=>t[props.itemName]).join(',');
        break;
      case "arrayStr":
        return list.map(t=>t[props.itemName]);
        break;
      case "arrayObj":
        return list;
        break;
      default :
        return ""
    }
  }
  //接收图片库选择后的结果，因为监听会出现冲突，使用事件接收
  function imgAdminRes(res){
    list.value=list.value.concat(res);
    urlList.value = list.value.map(item => item[props.itemName]);
    emit("update:modelValue", listToString(list.value));
  }
  function addImg(){
    proxy.$refs.ImgIndexRef.showOpen();
  }
  function showImgView(index){
    initialIndex.value=index;
    showViewer.value = true;
  }
  function deleteImg(index){
    list.value.splice(index,1);
    indexImgList.value.splice(index,1);
    emit("update:modelValue", listToString(list.value));
  }
  function draggableEnd(){
    emit("update:modelValue", listToString(list.value));
  }
</script>

<style scoped lang="scss">
  .img-list{
    >div{
      display: flex;
      flex-wrap: wrap;
    }
    .img-item{
      margin-right: 10px;
      margin-bottom: 10px;
      position: relative;
      box-shadow: 0 0 2px 1px #e0e0e0;
      border-radius: 2px;
      overflow: hidden;
      &:last-child{
        margin-right: 0;
      }
      .img-item-icon{
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        display: flex;
        align-items: center;
        justify-content: center;
        background: rgb(0 0 0 / 50%);
        opacity: 0;
        transition: .5s;
      }
      .icon-move{
        cursor: move;
      }
      &:hover{
        .img-item-icon {
          opacity: 1;
        }
      }

    }
    .add-icon{
      display: flex;
      align-items: center;
      justify-content: center;
      border: 1px dashed #dcdfe6;
      cursor: pointer;
      margin-bottom: 10px;
    }
  }
</style>
